"""
用户 | 接口
"""

from fastapi import (
    APIRouter,
    Depends,
)

import utils.enum_utils as enum
from biz import user_biz
from components.audit_log import audit
from components.depends import login_required
from components.global_param import get_user_id
from components.logger import log
from components.response import OKWithDataResponse
from models.request import (
    UserChangePasswordRequest,
    UserCheckRequest,
    UserDetailRequest,
    UserLoginRequest,
    UserPathField,
    UserRegisterRequest,
    UserUpdateRequest,
)
from models.response import (
    UserAuthenticatedResponse,
    UserCheckResponse,
    UserDetailResponse,
)
from models.vo import (
    UserAuthenticatedVO,
    UserCheckVO,
    UserDetailVO,
)
from utils.data_utils.special import ObjectIdStr

user_router: APIRouter = APIRouter(prefix="/user")
""" 用户 路由 """


@user_router.post(
    path="/check/",
    summary="用户 | 检查",
    response_model=UserCheckResponse,
)
@audit(
    model=enum.Model.USER,
    operation=enum.ModelOperation.CHECK,
)
async def user_check(request: UserCheckRequest) -> OKWithDataResponse:
    vo: UserCheckVO = user_biz.UserCheckHandler.check(request)
    log.info(f"[用户][检查] union_username: {request.union_username}")

    return OKWithDataResponse(vo)


@user_router.post(
    path="/register/",
    summary="用户 | 注册",
    response_model=UserAuthenticatedResponse,
)
@audit(
    model=enum.Model.USER,
    operation=enum.ModelOperation.REGISTER,
    po_id="response.data.user_id",
    fill_user_id=True,
)
async def user_register(request: UserRegisterRequest) -> OKWithDataResponse:
    vo: UserAuthenticatedVO = user_biz.UserRegisterHandler.register(request)
    log.info(f"[用户][注册] user_id: {vo.user_id}")

    return OKWithDataResponse(vo)


@user_router.post(
    path="/login/",
    summary="用户 | 登录",
    response_model=UserAuthenticatedResponse,
)
@audit(
    model=enum.Model.USER,
    operation=enum.ModelOperation.LOGIN,
    po_id="response.data.user_id",
    fill_user_id=True,
)
async def user_login(request: UserLoginRequest) -> OKWithDataResponse:
    vo: UserAuthenticatedVO = user_biz.UserLoginHandler.login(request)
    log.info(f"[用户][登录] user_id: {vo.user_id}")

    return OKWithDataResponse(vo)


@user_router.post(
    path="/change-password/",
    summary="用户 | 修改密码",
    response_model=UserDetailResponse,
    dependencies=[Depends(login_required)],
)
@audit(
    model=enum.Model.USER,
    operation=enum.ModelOperation.CHANGE_PASSWORD,
    po_id="response.data.user_id",
)
async def user_change_password(request: UserChangePasswordRequest) -> OKWithDataResponse:
    vo: UserDetailVO = user_biz.UserChangePasswordHandler.change_password(request)
    log.info(f"[用户][修改密码] user_id: {get_user_id()}")

    return OKWithDataResponse(vo)


@user_router.get(
    path="/me/",
    summary="用户 | 详情 | 我的",
    response_model=UserDetailResponse,
    dependencies=[Depends(login_required)],
)
@audit(
    model=enum.Model.USER,
    operation=enum.ModelOperation.DETAIL,
    po_id="response.data.user_id",
)
async def user_detail_me() -> OKWithDataResponse:
    user_id: ObjectIdStr = get_user_id()
    request: UserDetailRequest = UserDetailRequest(user_id=user_id)
    vo: UserDetailVO = user_biz.UserGetter.get_detail(request)
    log.info(f"[用户][详情][我的] user_id: {user_id}")

    return OKWithDataResponse(vo)


@user_router.get(
    path="/{user_id}/",
    summary="用户 | 详情",
    response_model=UserDetailResponse,
    dependencies=[Depends(login_required)],
)
@audit(
    model=enum.Model.USER,
    operation=enum.ModelOperation.DETAIL,
    po_id="user_id",
)
async def user_detail(user_id: ObjectIdStr = UserPathField.user_id) -> OKWithDataResponse:
    request: UserDetailRequest = UserDetailRequest(user_id=user_id)
    vo: UserDetailVO = user_biz.UserGetter.get_detail(request)
    log.info(f"[用户][详情] user_id: {get_user_id()} look user_id: {vo.user_id}")

    return OKWithDataResponse(vo)


@user_router.put(
    path="/me/",
    summary="用户 | 更新 | 我的",
    response_model=UserDetailResponse,
    dependencies=[Depends(login_required)],
)
@audit(
    model=enum.Model.USER,
    operation=enum.ModelOperation.UPDATE,
    po_id="response.data.user_id",
)
async def user_update_me(request: UserUpdateRequest) -> OKWithDataResponse:
    vo: UserDetailVO = user_biz.UserUpdateHandler.update(request)
    log.info(f"[用户][更新][我的] user_id: {get_user_id()}")

    return OKWithDataResponse(vo)
